<?php

namespace StudyBuddy\Controllers;

use \StudyBuddy\Utf8String;
use \StudyBuddy\WebPage;
use \StudyBuddy\TagsTokenizer;
use \StudyBuddy\Request;
use \StudyBuddy\Responder;

/**
 * Controller responsible
 * for processing retag form
 *
 */
class Retag extends WebPage
{
	protected $membersOnly = true;

	protected $requireToken = true;

	protected $aRequired = array('qid', 'tags');


	/**
	 * Question being deleted
	 *
	 * @var object of type Question
	 */
	protected $oQuestion;


	/**
	 * Array of old value of a_tags
	 *
	 * @var array
	 */
	protected $aOldTags = array();


	/**
	 * Array of tags that were added to
	 * Question as result of this retag
	 * Tags are not always added - a retag may
	 * be just a removal of some tags
	 * If any new tags were added this array will
	 * include new tags
	 *
	 * @var tags
	 */
	protected $aAddedTags = array();


	/**
	 * Array of submitted tags
	 * after they are run through TagsTokenizer
	 *
	 * @var array
	 */
	protected $aSubmitted;


	protected function main(){
		$this->aSubmitted = TagsTokenizer::factory($this->oRequest->getUTF8('tags'))->getArrayCopy();
		d('$this->aSubmitted: '.print_r($this->aSubmitted, 1));


		$this->validateSubmitted()
		->getQuestion()
		->checkPermission()
		->checkForChanges()
		->removeOldTags()
		->updateQuestion()
		->addNewTags()
		->postEvent()
		->returnResult();
	}


	/**
	 * Validate to make sure
	 * submitted form contains between 1 and 5 tags
	 *
	 * @throws \StudyBuddy\Exception if no tags or more than 5 tags
	 *
	 * @return object $this
	 */
	protected function validateSubmitted(){

		$min = $this->oRegistry->Ini->MIN_QUESTION_TAGS;
		$max = $this->oRegistry->Ini->MAX_QUESTION_TAGS;

		if(($min > 0) && empty($this->aSubmitted)){
			/*
			 * @todo translate string
			 */
			throw new \StudyBuddy\Exception('No valid tags have been submitted. Please use words that best categorize this question');
		}

		$count = count($this->aSubmitted);

		if($count < $min){
			/**
			 * @todo Translate string
			 */
			throw new \StudyBuddy\Exception('Question must have at least '.$min.' tag(s)');
		}

		if($count > $max){
			/**
			 * @todo translate string
			 */
			throw new \StudyBuddy\Exception('Question cannot have more than '.$max.' tags. Please remove some tags');
		}

		return $this;
	}


	/**
	 * Create $this->oQuestion object
	 *
	 * @throws \StudyBuddy\Exception if question
	 * not found or is marked as deleted
	 *
	 * @return object $this
	 */
	protected function getQuestion(){

		$a = $this->oRegistry->Mongo->QUESTIONS->findOne(array('_id' => (int)$this->oRequest['qid']));
		d('a: '.print_r($a, 1));

		if(empty($a) || !empty($a['i_del_ts'])){

			throw new \StudyBuddy\Exception('Question not found');
		}

		$this->oQuestion = new \StudyBuddy\Question($this->oRegistry, $a);
		$this->aOldTags = $this->oQuestion['a_tags'];

		return $this;
	}


	/**
	 * Check to make sure Viewer has permission
	 * to retag.
	 * Permitted to retag are: owner of question,
	 * moderator/admin or user with reputation
	 *
	 * @return object $this
	 *
	 */
	protected function checkPermission(){

		if(!\StudyBuddy\isOwner($this->oRegistry->Viewer, $this->oQuestion)
		&& ($this->oRegistry->Viewer->getReputation() < \StudyBuddy\Points::RETAG)){

			$this->checkAccessPermission('retag');
		}

		return $this;
	}


	/**
	 * Make sure that new tags are
	 * different from tags that already
	 * in the question
	 *
	 * @throws \StudyBuddy\Exception in case tags
	 * has not changed
	 *
	 * @return object $this
	 */
	protected function checkForChanges(){

		$this->aAddedTags = \array_diff($this->aSubmitted, $this->aOldTags);
		$diff2 = \array_diff($this->aOldTags, $this->aSubmitted);
		d('diff: '.print_r($this->aAddedTags, 1));
		d('diff2: '.print_r($diff2, 1));
		if(empty($this->aAddedTags) && empty($diff2)){
			throw new \StudyBuddy\Exception('You have not changed any tags');
		}

		return $this;
	}


	/**
	 * Update USER_TAGS and QUESTION_TAGS and RELATED_TAGS collections
	 * to remove old tags that belong to this questions
	 *
	 * @return object $this
	 */
	protected function removeOldTags(){
		\StudyBuddy\Qtagscounter::factory($this->oRegistry)->removeTags($this->oQuestion);
		\StudyBuddy\UserTags::factory($this->oRegistry)->removeTags($this->oQuestion);
		\StudyBuddy\Relatedtags::factory($this->oRegistry)->removeTags($this->oQuestion);
		/**
		 * Also update UNANSWERED_TAGS if this question
		 * is unanswered
		 */
		if(0 === $this->oQuestion['i_sel_ans']){
			d('going to remove from Unanswered tags');
			\StudyBuddy\UnansweredTags::factory($this->oRegistry)->remove($this->oQuestion);
		}

		return $this;
	}


	/**
	 * Update USER_TAGS and QUESTION_TAGS collections
	 * to add new tags that belong to this questions
	 *
	 * @return object $this
	 */
	protected function addNewTags(){
		if(count($this->aSubmitted) > 0){
			\StudyBuddy\Qtagscounter::factory($this->oRegistry)->parse($this->oQuestion);
			\StudyBuddy\UserTags::factory($this->oRegistry)->addTags($this->oQuestion['i_uid'], $this->oQuestion);
			\StudyBuddy\Relatedtags::factory($this->oRegistry)->addTags($this->oQuestion);

			if(0 === $this->oQuestion['i_sel_ans']){
				d('going to add to Unanswered tags');
				\StudyBuddy\UnansweredTags::factory($this->oRegistry)->set($this->oQuestion);
			}
		}
		
		return $this;
	}


	/**
	 * Update question object with
	 * new values related to tags
	 *
	 * @return object $this
	 */
	protected function updateQuestion(){

		$this->oQuestion->retag($this->oRegistry->Viewer, $this->aSubmitted)
		->save();
		$this->makeActionCount('retag_total', $this->oRegistry->Viewer->getUid());
		return $this;
	}
	
	//hoangto make action count
	function makeActionCount($countType = '', $uid = 0){
	
		$coll = $this->oRegistry->Mongo->ACTIONCOUNT;
	
		$count = $coll->findOne(array('i_uid' => $uid), array('_id',$countType));
		
		if(empty($count[$countType])){
			$total = 1;
		}else{
			$total = (int)$count[$countType] + 1;
		}
			
		if(empty($count['_id'])){
			$countData = array(
				'i_uid' => $uid,
				$countType => $total
			);
			$this->oRegistry->Mongo->ACTIONCOUNT->insert($countData);
		}else{
			$countData = array(
				'$set' => array($countType => $total)
			);
			$this->oRegistry->Mongo->ACTIONCOUNT->update(array('i_uid' => $uid),$countData);
		}
		
		$coll->ensureIndex(array('i_uid' => 1));
		
		$this->checkGainBadges($countType, $uid);
		
		return $this;
	}

	//hoangto
	protected function checkGainBadges($countType, $uid){
		
		$count = $this->oRegistry->Mongo->ACTIONCOUNT->findOne(array('i_uid' => $uid), array($countType));
		$cond = $this->oRegistry->Mongo->BADGES->find(array('cond_type' => $countType, 'cond' => array('$lt' => $count[$countType])));
		
		foreach($cond as $obj){
			$actData = array(
				'i_uid' => $uid,
				'username' => $this->oRegistry->Viewer->getDisplayName(),
				'i_bid' => $obj['id'],
				'badges' => $obj['b_name'],
				'badges_type' => $obj['type']
			);
			$isExist = $this->oRegistry->Mongo->USER_BADGES->findOne($actData);
			if(empty($isExist)){
				$this->oRegistry->Mongo->USER_BADGES->insert($actData);
				$this->makeActivities('badges', 'earned a badges', $obj['id']);
			}
			$this->oRegistry->Mongo->USER_BADGES->ensureIndex(array('i_uid' => 1));
			$this->oRegistry->Mongo->USER_BADGES->ensureIndex(array('badges' => 1));
		}
		
		return $this;
	}
	
	//hoangto make answer activity
	protected function makeActivities($act_type = 'a', $act_name = 'answered a question', $act_id) {
		$actData = array(
			'i_uid' => $this->oRegistry->Viewer->getUid(),
			'username' => $this->oRegistry->Viewer->getDisplayName(),
			'avt' => $this->oRegistry->Viewer->getAvatarSrc(),
			'act_type' => $act_type,
			'act_id' => $act_id,
			'act_name' => $act_name,
			'i_ts' => time(),
			'hts' => date('F j, Y g:i a T')
		);
	
		$coll = $this->oRegistry->Mongo->ACTIVITIES;
		$coll->ensureIndex(array('i_uid' => 1));
		$coll->ensureIndex(array('i_ts' => 1));
		
		$oActivity = \StudyBuddy\MongoDoc::factory($this->oRegistry, 'ACTIVITIES', $actData);
		$res = $oActivity->save($actData);
		
		return $this;
	}

	/**
	 * Post onRetag event
	 *
	 * @return object $this
	 */
	protected function postEvent(){
		$this->oRegistry->Dispatcher->post($this->oQuestion, 'onRetag', $this->aAddedTags);

		return $this;
	}


	protected function returnResult(){
		/**
		 * @todo translate string
		 */
		$message = 'Question retagged successfully';

		if(Request::isAjax()){
			$ret = array('reload' => 100); //'alert' => $message,

			Responder::sendJSON($ret);
		}

		Responder::redirectToPage($this->oQuestion->getUrl());
	}

}
